using Baci.Net.ToolKit.ArcGISProGeoprocessor.Models;
using Baci.Net.ToolKit.ArcGISProGeoprocessor.Models.Attributes;
using Baci.Net.ToolKit.ArcGISProGeoprocessor.Models.Attributes.DomainAttributes;
using Baci.Net.ToolKit.ArcGISProGeoprocessor.Models.Enums;
using System.Collections.Generic;
using System.ComponentModel;

namespace Baci.ArcGIS._RasterAnalysisTools._AnalyzePatterns
{
    /// <summary>
    /// <para>Calculate Density</para>
    /// <para>Creates a density map from point or line features by spreading known quantities of some phenomenon (represented as attributes of the points or lines) across the map. The result is a layer of areas classified from least dense to most dense.</para>
    /// <para>通过在地图上散布某些现象的已知数量（表示为点或线的属性），从点或线要素创建密度地图。结果是将区域图层从密度从最低到最高。</para>
    /// </summary>    
    [DisplayName("Calculate Density")]
    public class CalculateDensity : AbstractGPProcess
    {
        /// <summary>
        /// 无参构造
        /// </summary>
        public CalculateDensity()
        {

        }

        /// <summary>
        /// 有参构造
        /// </summary>
        /// <param name="_inputPointOrLineFeatures">
        /// <para>Input Point or Line Features</para>
        /// <para>The input point or line features that will be used to calculate the density raster.</para>
        /// <para>将用于计算密度栅格的输入点或线要素。</para>
        /// </param>
        /// <param name="_outputName">
        /// <para>Output Name</para>
        /// <para><xdoc>
        ///   <para>The name of the output raster service.</para>
        ///   <para>The default name is based on the tool name and the input layer name. If the layer name already exists, you will be prompted to provide another name.</para>
        /// </xdoc></para>
        /// <para><xdoc>
        ///   <para>输出栅格服务的名称。</para>
        ///   <para>默认名称基于工具名称和输入图层名称。如果图层名称已存在，系统将提示您提供其他名称。</para>
        /// </xdoc></para>
        /// </param>
        public CalculateDensity(object _inputPointOrLineFeatures, object _outputName)
        {
            this._inputPointOrLineFeatures = _inputPointOrLineFeatures;
            this._outputName = _outputName;
        }
        public override string ToolboxName => "Raster Analysis Tools";

        public override string ToolName => "Calculate Density";

        public override string CallName => "ra.CalculateDensity";

        public override List<string> AcceptEnvironments => ["cellSize", "extent", "mask", "outputCoordinateSystem", "snapRaster"];

        public override object[] ParameterInfo => [_inputPointOrLineFeatures, _outputName, _countField, _searchDistance, _outputAreaUnits.GetGPValue(), _outputCellSize, _outputRaster, _inBarriers];

        /// <summary>
        /// <para>Input Point or Line Features</para>
        /// <para>The input point or line features that will be used to calculate the density raster.</para>
        /// <para>将用于计算密度栅格的输入点或线要素。</para>
        /// <para></para>
        /// </summary>
        [DisplayName("Input Point or Line Features")]
        [Description("")]
        [Option(OptionTypeEnum.Must)]
        public object _inputPointOrLineFeatures { get; set; }


        /// <summary>
        /// <para>Output Name</para>
        /// <para><xdoc>
        ///   <para>The name of the output raster service.</para>
        ///   <para>The default name is based on the tool name and the input layer name. If the layer name already exists, you will be prompted to provide another name.</para>
        /// </xdoc></para>
        /// <para><xdoc>
        ///   <para>输出栅格服务的名称。</para>
        ///   <para>默认名称基于工具名称和输入图层名称。如果图层名称已存在，系统将提示您提供其他名称。</para>
        /// </xdoc></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Output Name")]
        [Description("")]
        [Option(OptionTypeEnum.Must)]
        public object _outputName { get; set; }


        /// <summary>
        /// <para>Count Field</para>
        /// <para>A field indicating the number of incidents at each location. For example, if you are making a population density raster, and the input points are cities, it is appropriate to use the population of the city for the count field so cities with larger populations have more impact on the density calculations.</para>
        /// <para>指示每个位置的事件数的字段。例如，如果要制作人口密度栅格，并且输入点为城市，则将城市的人口用于计数字段是合适的，这样人口较大的城市对密度计算的影响更大。</para>
        /// <para></para>
        /// </summary>
        [DisplayName("Count Field")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public object _countField { get; set; } = null;


        /// <summary>
        /// <para>Search Distance</para>
        /// <para><xdoc>
        ///   <para>The search distance and units for the distance. When calculating the density of a cell, all features within this distance will be used in the density calculation for that cell.</para>
        ///   <para>The units can be Kilometers, Meters, Miles, or Feet.</para>
        ///   <para>The default units are Meters.</para>
        /// </xdoc></para>
        /// <para><xdoc>
        ///   <para>搜索距离和距离的单位。计算像元密度时，此距离内的所有要素都将用于该像元的密度计算。</para>
        ///   <para>单位可以是公里、米、英里或英尺。</para>
        ///   <para>默认单位为米。</para>
        /// </xdoc></para>
        /// <para>单位： Meters | Kilometers | Feet | Miles </para>
        /// </summary>
        [DisplayName("Search Distance")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public string? _searchDistance { get; set; } = null;


        /// <summary>
        /// <para>Output Area Units</para>
        /// <para><xdoc>
        ///   <para>Specifies the units that will be used for calculating area. Density is count divided by area, and this parameter sets the units of the area in the density calculation.</para>
        ///   <bulletList>
        ///     <bullet_item>Square Meters—Calculate the density per square meter. This is the default.</bullet_item><para/>
        ///     <bullet_item>Square Kilometers—Calculate the density per square kilometer.</bullet_item><para/>
        ///     <bullet_item>Square Feet—Calculate the density per square foot.</bullet_item><para/>
        ///     <bullet_item>Square Miles—Calculate the density per square mile.</bullet_item><para/>
        ///   </bulletList>
        /// </xdoc></para>
        /// <para><xdoc>
        ///   <para>指定将用于计算面积的单位。密度是计数除以面积，此参数在密度计算中设置面积的单位。</para>
        ///   <bulletList>
        ///     <bullet_item>平方米 - 计算每平方米的密度。这是默认设置。</bullet_item><para/>
        ///     <bullet_item>平方公里 - 计算每平方公里的密度。</bullet_item><para/>
        ///     <bullet_item>平方英尺 - 计算每平方英尺的密度。</bullet_item><para/>
        ///     <bullet_item>平方英里 - 计算每平方英里的密度。</bullet_item><para/>
        ///   </bulletList>
        /// </xdoc></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Output Area Units")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public _outputAreaUnits_value? _outputAreaUnits { get; set; } = null;

        public enum _outputAreaUnits_value
        {
            /// <summary>
            /// <para>Square Meters</para>
            /// <para>Square Meters—Calculate the density per square meter. This is the default.</para>
            /// <para>平方米 - 计算每平方米的密度。这是默认设置。</para>
            /// </summary>
            [Description("Square Meters")]
            [GPEnumValue("Square Meters")]
            _Square_Meters,

            /// <summary>
            /// <para>Square Kilometers</para>
            /// <para>Square Kilometers—Calculate the density per square kilometer.</para>
            /// <para>平方公里 - 计算每平方公里的密度。</para>
            /// </summary>
            [Description("Square Kilometers")]
            [GPEnumValue("Square Kilometers")]
            _Square_Kilometers,

            /// <summary>
            /// <para>Square Feet</para>
            /// <para>Square Feet—Calculate the density per square foot.</para>
            /// <para>平方英尺 - 计算每平方英尺的密度。</para>
            /// </summary>
            [Description("Square Feet")]
            [GPEnumValue("Square Feet")]
            _Square_Feet,

            /// <summary>
            /// <para>Square Miles</para>
            /// <para>Square Miles—Calculate the density per square mile.</para>
            /// <para>平方英里 - 计算每平方英里的密度。</para>
            /// </summary>
            [Description("Square Miles")]
            [GPEnumValue("Square Miles")]
            _Square_Miles,

        }

        /// <summary>
        /// <para>Output Cell Size</para>
        /// <para><xdoc>
        ///   <para>The cell size and units for the output raster.</para>
        ///   <para>The units can be Kilometers, Meters, Miles, or Feet.</para>
        ///   <para>The default units are Meters.</para>
        /// </xdoc></para>
        /// <para><xdoc>
        ///   <para>输出栅格的像元大小和单位。</para>
        ///   <para>单位可以是公里、米、英里或英尺。</para>
        ///   <para>默认单位为米。</para>
        /// </xdoc></para>
        /// <para>单位： Meters | Kilometers | Feet | Miles </para>
        /// </summary>
        [DisplayName("Output Cell Size")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public string? _outputCellSize { get; set; } = null;


        /// <summary>
        /// <para>Output Raster</para>
        /// <para></para>
        /// <para></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Output Raster")]
        [Description("")]
        [Option(OptionTypeEnum.derived)]
        public object _outputRaster { get; set; }


        /// <summary>
        /// <para>Input Barrier Features</para>
        /// <para><xdoc>
        ///   <para>The dataset that defines the barriers.</para>
        ///   <para>The barriers can be a feature layer of polyline or polygon features.</para>
        /// </xdoc></para>
        /// <para><xdoc>
        ///   <para>定义障碍的数据集。</para>
        ///   <para>障碍可以是折线或面要素的要素图层。</para>
        /// </xdoc></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Input Barrier Features")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public object _inBarriers { get; set; } = null;


        public CalculateDensity SetEnv(object cellSize = null, object extent = null, object mask = null, object outputCoordinateSystem = null, object snapRaster = null)
        {
            base.SetEnv(cellSize: cellSize, extent: extent, mask: mask, outputCoordinateSystem: outputCoordinateSystem, snapRaster: snapRaster);
            return this;
        }

    }

}